from net_controller import *
import sys
from ops import *
from optparse import OptionParser
import re

DELAY = 3
TIMEOUT = 1
commandList = [(OPS.ADD, ("name1","url1")),(OPS.ADD, ("name2","url2"))]

class PaxosClient:
    def __init__(self, proc_id, command_file, options, config_path='config.json'):
        self.command_file = command_file
        self.cid = 0
        self.delay = options.delay
        self.netController = NetController(proc_id, None, config_path)
        self.serv_id = -1
        self.status = OPS.NULL

    def parseCommand(self, commandstring):

        command = None
        results = re.split('\W+', commandstring)

        if results[0] == "add":
            command = self.addCommand(results[1], results[2])
        elif results[0] == "delete":
            command = self.deleteCommand(results[1])
        elif results[0] == "edit":
            command = self.editCommand(results[1], results[2])
        elif results[0] == "print":
            command = self.printCommand()

        print
        print commandstring.rstrip()

        return command

    def addCommand(self, key, url):
        return (OPS.ADD, (self.cid, key, url))

    def deleteCommand(self, key):
        return (OPS.DEL, (self.cid, key))

    def editCommand(self, key, url):
        return (OPS.EDT, (self.cid, key, url))

    def printCommand(self):
        return (OPS.PRT, (self.cid,))

    def getStatus(self):
        return self.status

    def setServer(self, serv_id):
        self.serv_id = serv_id

    def send(self, command):
        self.status = command[0]
        #print "Sending to", self.serv_id, "the command", command
        if self.serv_id >= 0:
            self.netController.send(self.serv_id, command, self.delay)

    def next(self):
        ret = self.netController.next(True,TIMEOUT)
        if ret == None:
            return
        #print "Recieved", ret
        from_proc, msg = ret
        msgType = msg[0]
        if msgType == self.status:
            self.status = OPS.NULL
            if msgType == OPS.PRT:
                print(msg[1])
        elif msgType == OPS.LEADERBROAD:
            if self.serv_id != from_proc:
                print "New Leader", from_proc
                self.serv_id = from_proc
                self.status = OPS.RESEND
            else:
                pass
        else:
            pass
 
    def run(self):

        print "Running client..."

        f = open(self.command_file)
        command_list = f.readlines()
        command = None

        while True:
            if self.getStatus() == OPS.NULL:
                if command_list:
                    self.cid += 1
                    command = self.parseCommand(command_list.pop(0))
                    self.send(command)
            elif self.getStatus() == OPS.RESEND:
                self.send(command)
            else:
                self.next()


if __name__ == "__main__":

    usage = "usage: %prog [options] proc_id command_file"
    parser = OptionParser(usage=usage)

    parser.add_option("-d", "--delay", default=0, dest="delay",
                      help="set message delay", metavar="<n>", type="int")


    (options, args) = parser.parse_args()

    if len(args) < 2:
        parser.print_help()
        sys.exit(1)

    print "delay =   ", options.delay
    print "file =    ", args[1]
    print "proc_id = ", args[0]

    client = PaxosClient(int(args[0]), args[1], options)
    client.run()
